home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************
-
- Conference Server/Service written by Jeffrey A. Litz
-
- litz@cs.uwp.edu -or- Jeff_Litz@EDTNG.Kenosha.WI.US
-
- Copyright ©1994 JL Productions.
- *************************************************************************/
-
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <exec/ports.h>
- #include <exec/semaphores.h>
- #include <exec/io.h>
- #include <devices/printer.h>
- #include <devices/timer.h>
- #include <devices/parallel.h>
- #include <devices/serial.h>
-
- #include <intuition/intuition.h>
- #include <intuition/classes.h>
- #include <intuition/classusr.h>
- #include <intuition/imageclass.h>
- #include <intuition/gadgetclass.h>
- #include <libraries/gadtools.h>
- #include <graphics/displayinfo.h>
- #include <graphics/gfxbase.h>
- #include <clib/intuition_protos.h>
- #include <clib/gadtools_protos.h>
- #include <clib/graphics_protos.h>
-
- #include <envoy/nipc.h>
- #include <envoy/services.h>
- #include <proto/intuition.h>
-
- #include <pragmas/exec_pragmas.h>
- #include <pragmas/nipc_pragmas.h>
- #include <pragmas/dos_pragmas.h>
- #include <pragmas/utility_pragmas.h>
-
- #include <utility/tagitem.h>
- #include <clib/dos_protos.h>
- #include <clib/exec_protos.h>
- #include <clib/nipc_protos.h>
- #include <clib/alib_protos.h>
- #include <clib/utility_protos.h>
-
- #include "string.h"
-
- extern KPrintF(STRPTR,...);
-
-
-
-
- /*************************************************************************
- Some structures & definitions for the conference service.
- Should go into a .h file.
- *************************************************************************/
- #include "tkbase.h"
-
- #define TKCMD_TALK 1
- #define TKCMD_ABORT 2
- #define TKCMD_DATA 3
- #define TKCMD_CONFERENCE 4
- #define TKCMD_CONDATA 5
- #define TKCMD_CONEND 6
- #define TKCMD_CONLIST 7
- #define TKCMD_CLDATA 8
- #define TKCMD_CLEND 9
- #define TKCMD_MALIST 10
- #define TKCMD_STATUS 11
- #define TKCMD_PRIVATE 12
-
- struct Con_Node
- {
- struct Node cnode;
- UBYTE con_name[32];
- struct List machine_list;
- ULONG flags;
- };
-
- struct Hide_Node
- {
- struct Node hnode;
- UBYTE h_name[32];
- ULONG mode;
- };
-
- struct Machine_Node
- {
- struct Node mnode;
- UBYTE m_id[8];
- UBYTE m_name[32];
- UBYTE alias[32];
- struct List hide_list;
- ULONG flags;
- void *s_entity;
- };
-
- struct TagItem cbtags[2] =
- {
- ENT_AllocSignal, NULL,
- TAG_END, 0
- };
-
- struct TagItem ttags[3] =
- {
- TRN_AllocReqBuffer,516,
- TRN_AllocRespBuffer,4,
- TAG_END, 0
- };
-
-
- extern STRPTR TKSUser;
- extern STRPTR TKSPassword;
- extern STRPTR TKSEntityName;
- extern ULONG TKSSignalMask;
- extern ULONG TKSError;
- extern struct Task *TKSSMProc;
- extern TKSServer(void);
-
- extern struct Node *CFindName(struct List *cc_list,UBYTE *string);
-
-
-
-
- /**************************************************************************
- StartService() - Starts the service.
-
- Services Manager calls this function to attempt to start the service.
-
- INPUTS: TagList passed in by Services Manager
- OUTPUT: Error Code - Non Zero Means Error
- **************************************************************************/
- ULONG __saveds ASM StartService(REG(a0) struct TagItem *st_list)
- {
- struct TagItem cptags[3];
- struct Process *lpdproc;
- BOOL status = FALSE;
- UBYTE sigbit;
- struct TagItem *tag;
-
-
- /* Check to see if service is already open */
-
- if(!TKSBase->TKS_Entity)
- {
- /* Nope - Try starting it up */
-
- if(sigbit = AllocSignal(-1L))
- {
- TKSSMProc = FindTask(0L);
- TKSSignalMask = (1L<<sigbit);
-
- cptags[0].ti_Tag = NP_Entry;
- cptags[0].ti_Data = (ULONG) TKSServer;
- cptags[1].ti_Tag = NP_Name;
- cptags[1].ti_Data = (ULONG) "CF Daemon";
- cptags[2].ti_Tag = TAG_DONE;
- cptags[2].ti_Data = NULL;
-
-
- /* Process tags passed in by services manager */
-
- if(tag=FindTagItem(SSVC_UserName,st_list))
- {
- TKSUser = (STRPTR) tag->ti_Data;
- }
-
- if(tag=FindTagItem(SSVC_Password,st_list))
- {
- TKSPassword = (STRPTR) tag->ti_Data;
- }
-
- if(tag=FindTagItem(SSVC_EntityName,st_list))
- {
- TKSEntityName = (STRPTR) tag->ti_Data;
- }
-
-
- /* Try to start the process */
-
- if(lpdproc = CreateNewProc((struct TagItem *)cptags))
- {
- Wait(1L<<sigbit);
- status = TRUE;
- }
- FreeSignal(sigbit);
- }
- }
- else
- {
- /* Service process already running... simply pass back its entity name */
-
- if(tag=FindTagItem(SSVC_EntityName,st_list))
- {
- strcpy((STRPTR)tag->ti_Data,"CF_Service");
- TKSError = 0;
- } else
- {
- TKSError = -1;
- }
- }
- return(TKSError);
- }
-
-
-
-
- /*************************************************************************
- GetServiceAttrsA() - Get service attributes
-
- Required to return the name of the service in tag SVCAttrs_Name
-
- INPUTS: TagList from services manager to process/update
- *************************************************************************/
- VOID ASM GetServiceAttrsA(REG(a0) struct TagItem *tagList)
- {
- struct TagItem *ti;
-
- if(ti=FindTagItem( SVCAttrs_Name, tagList))
- {
- strcpy((STRPTR)ti->ti_Data,"Conf_Service");
- }
- }
-
-
-
-
- /**************************************************************************
- Server() - Actual guts of the service
-
- The Conference Service Main Routine. Keeps track of all conferences,
- who in them, the "status" of each user, etc.
-
- Waits for any incoming transcation from our public entity.
-
- Called by an ASM stub called TKSServer.
-
- INPUTS: A0 - UserName, A1 - Password, A2 - EntityName
- OUTPUT: Global Var TKSError (only if a startup error occurs)
- **************************************************************************/
- VOID ASM Server(REG(a0) STRPTR userName,
- REG(a1) STRPTR password,
- REG(a2) STRPTR EntityName)
- {
- /* Quite a few variables - should be corrected with allocmen() */
-
- struct Library *SvcBase;
- ULONG CON_ID;
- ULONG signals;
- ULONG waitmask;
- ULONG StartupError;
- ULONG ent_sigbit;
- UBYTE host_name[256];
- UBYTE con_name[256],hos_name[256],machine_id[256],alias[256],machine_name[256];
- UBYTE pri_msg[512];
- UBYTE done;
- UWORD cnt;
- ULONG mem_p,error,cycle_mode;
- void *entity,*t_entity,*s_entity;
- struct Transaction *trans,*a_trans;
- struct List conference_list;
- struct Con_Node *c_node,*c_node2;
- struct Machine_Node *m_node,*m2_node,*mm_node,*m_node2;
- struct Hide_Node *m3_node,*m4_node;
- struct Hide_Node *h_node,*h_node2;
- struct TagItem cetags[4];
-
- ULONG m3mode,m4mode;
-
-
- /* Initialize a bunch of things */
-
- geta4();
-
- cetags[0].ti_Tag = ENT_Name;
- cetags[0].ti_Data = (ULONG) "CF_Service";
- cetags[1].ti_Tag = ENT_Public;
- cetags[1].ti_Data = (ULONG) TRUE;
- cetags[2].ti_Tag = ENT_AllocSignal;
- cetags[2].ti_Data = (ULONG) &ent_sigbit;
- cetags[3].ti_Tag = TAG_END;
- cetags[3].ti_Data = (ULONG) NULL;
-
- ent_sigbit = 0;
- CON_ID = 0;
-
- NewList(&conference_list);
-
- StartupError = -1;
-
-
- /* Start of service */
-
- if(SvcBase = OpenLibrary("conf.service", 0L))
- {
- /* Create our entity for everyone to communicate with us */
-
- if(entity = CreateEntityA((struct TagItem *) cetags))
- {
- /* Find out who we are */
-
- GetHostName(entity,host_name,255);
-
- if(t_entity=CreateEntityA((struct TagItem *) cbtags))
- {
- /* Alloc our transaction */
-
- if(a_trans=AllocTransactionA((struct TagItem *) ttags))
- {
- /* Everything allocated - setup and signal we are ready */
-
- TKSBase->TKS_Entity = entity;
- strcpy(EntityName,"CF_Service");
-
- TKSError = StartupError = 0;
-
- Signal(TKSSMProc, TKSSignalMask);
- waitmask = (1<<ent_sigbit);
- done = 0;
-
-
- /* Wait for a transaction */
-
- while(TRUE)
- {
- signals = Wait(waitmask);
- if(signals & (1<<ent_sigbit))
- {
- if(trans = GetTransaction(entity))
- {
- /* Process a TKCMD_CONFERENCE Transaction */
- /* Create or enter a conference */
-
- if(trans->trans_Command == TKCMD_CONFERENCE)
- {
- error=1;
- strcpy(con_name,(UBYTE *)trans->trans_RequestData+4);
- strcpy(hos_name,(UBYTE *)trans->trans_RequestData+36);
- strcpy(alias,(UBYTE *)trans->trans_RequestData+68);
- if(s_entity = FindEntity(hos_name,con_name,t_entity,NULL))
- {
- if(c_node=(struct Con_Node *)CFindName(&conference_list,con_name))
- {
- if(!CFindName(&c_node->machine_list,hos_name))
- {
- if(m_node=AllocMem(sizeof(struct Machine_Node),0))
- {
- strcpy(m_node->m_name,hos_name);
- strcpy(m_node->alias,alias);
- m_node->mnode.ln_Name=m_node->m_id;
- m_node->flags=0;
- m_node->s_entity=s_entity;
- NewList(&m_node->hide_list);
- sprintf(m_node->m_id,"%ld",CON_ID);
- AddTail(&c_node->machine_list,(struct Node *)m_node);
- error=0;
- }
- }
- }
- else
- {
- if(c_node=(struct Con_Node *)AllocMem(sizeof(struct Con_Node),0))
- {
- strcpy(c_node->con_name,con_name);
- c_node->cnode.ln_Name=c_node->con_name;
- c_node->flags=0;
- NewList(&c_node->machine_list);
- if(m_node=(struct Machine_Node *)AllocMem(sizeof(struct Machine_Node),0))
- {
- strcpy(m_node->m_name,hos_name);
- strcpy(m_node->alias,alias);
- m_node->mnode.ln_Name=m_node->m_id;
- m_node->flags=0;
- m_node->s_entity=s_entity;
- NewList(&m_node->hide_list);
- sprintf(m_node->m_id,"%ld",CON_ID);
- AddTail(&c_node->machine_list,(struct Node *)m_node);
- AddTail(&conference_list,(struct Node *)c_node);
- error=0;
- }
- else
- {
- FreeMem(c_node,sizeof(struct Con_Node));
- }
- }
- }
- }
- trans->trans_Error=error;
- trans->trans_RespDataActual=4;
- *(ULONG *)trans->trans_ResponseData=(ULONG) CON_ID;
- ReplyTransaction(trans);
-
- ++CON_ID;
- }
- else if(trans->trans_Command == TKCMD_CONDATA)
- {
- /* Process a TKCMD_CONDATA Transaction */
- /* Go through list and distribute data to appropriate machines */
-
- *(ULONG *)(a_trans->trans_RequestData)=*(ULONG *)(trans->trans_RequestData);
- strcpy(((UBYTE *)a_trans->trans_RequestData+4),((UBYTE *)trans->trans_RequestData+4));
- a_trans->trans_ReqDataActual=strlen(((UBYTE *)a_trans->trans_RequestData+4))+5;
- a_trans->trans_Command=TKCMD_CONDATA;
- sprintf(machine_id,"%ld",*(ULONG *)trans->trans_RequestData);
- ReplyTransaction(trans);
-
- for(c_node=(struct Con_Node *)conference_list.lh_Head;c_node->cnode.ln_Succ;c_node=(struct Con_Node *)c_node->cnode.ln_Succ)
- {
- if(m_node=(struct Machine_Node *)CFindName(&c_node->machine_list,machine_id))
- {
- for(m2_node=(struct Machine_Node *)c_node->machine_list.lh_Head;m2_node->mnode.ln_Succ;m2_node=(struct Machine_Node *)m2_node->mnode.ln_Succ)
- {
- if(stricmp(machine_id,m2_node->m_id))
- {
- /* Find the node pointer to another machine in the conference */
-
- if( m3_node = (struct Hide_Node *) CFindName(&m_node->hide_list,m2_node->m_name))
- {
- m3mode=m3_node->mode;
- } else
- {
- m3mode=0;
- }
-
- /* Find the node pointer to the machine sending the message */
-
- if(m4_node=(struct Hide_Node *)CFindName(&m2_node->hide_list,m_node->m_name))
- {
- m4mode=m4_node->mode;
- } else
- {
- m4mode=0;
- }
-
- if( ((m3mode==0) && ((m4mode==0) || (m4mode==1))) || ((m3mode==2) && ((m4mode==0) || (m4mode==1))))
- {
- cnt=2;
- while(cnt)
- {
- a_trans->trans_Timeout=10;
- DoTransaction(m2_node->s_entity,t_entity,a_trans);
- if(a_trans->trans_Error == 0)
- {
- break;
- }
- --cnt;
- }
- if(!cnt)
- {
- /* The machine being sent to couldn't be found - remove it!!! */
-
- for(c_node2=(struct Con_Node *)conference_list.lh_Head;c_node2->cnode.ln_Succ;c_node2=(struct Con_Node *)c_node2->cnode.ln_Succ)
- {
- if(m_node2=(struct Machine_Node *)CFindName(&c_node2->machine_list,m2_node->m_id))
- {
- Remove((struct Node*)m_node2);
- LoseEntity(m_node2->s_entity);
- while(h_node2=(struct Hide_Node *)RemHead(&m_node2->hide_list))
- {
- FreeMem(h_node2,sizeof(struct Hide_Node));
- }
- FreeMem(m_node2,sizeof(struct Machine_Node));
- if(c_node2->machine_list.lh_Head->ln_Succ == NULL)
- {
- Remove((struct Node *)c_node2);
- FreeMem(c_node2,sizeof(struct Con_Node));
- }
- break;
- }
- }
- }
- }
- }
- }
- break;
- }
- }
- }
- else if(trans->trans_Command == TKCMD_CONEND)
- {
- /* Process a TKCMD_CONEND transaction */
- /* Leave a conference and remove if last member */
-
- sprintf(machine_id,"%ld",*((ULONG *)trans->trans_RequestData));
- for(c_node=(struct Con_Node *)conference_list.lh_Head;c_node->cnode.ln_Succ;c_node=(struct Con_Node *)c_node->cnode.ln_Succ)
- {
- if(m_node=(struct Machine_Node *)CFindName(&c_node->machine_list,machine_id))
- {
- Remove((struct Node*)m_node);
- LoseEntity(m_node->s_entity);
- while(h_node=(struct Hide_Node *)RemHead(&m_node->hide_list))
- {
- FreeMem(h_node,sizeof(struct Hide_Node));
- }
- FreeMem(m_node,sizeof(struct Machine_Node));
- if(c_node->machine_list.lh_Head->ln_Succ == NULL)
- {
- Remove((struct Node *)c_node);
- FreeMem(c_node,sizeof(struct Con_Node));
- }
- break;
- }
- }
- ReplyTransaction(trans);
- }
- else if(trans->trans_Command == TKCMD_CONLIST)
- {
- /* Return a list of available conferences */
-
- strcpy(hos_name,(UBYTE *)trans->trans_RequestData+4);
- s_entity = FindEntity(hos_name,"Conference_List",t_entity,NULL);
-
- if(s_entity)
- {
- trans->trans_Error=0;
- ReplyTransaction(trans);
-
- mem_p=4;
- for(c_node=(struct Con_Node *)conference_list.lh_Head;c_node->cnode.ln_Succ;c_node=(struct Con_Node *)c_node->cnode.ln_Succ)
- {
- strcpy(((UBYTE *)a_trans->trans_RequestData+mem_p),c_node->con_name);
- mem_p+=32;
- if(mem_p == 516)
- {
- a_trans->trans_ReqDataActual=516;
- a_trans->trans_Command=TKCMD_CLDATA;
- a_trans->trans_Timeout=10;
- DoTransaction(s_entity,t_entity,a_trans);
- mem_p=4;
- }
- }
- if(mem_p != 4)
- {
- a_trans->trans_ReqDataActual=mem_p;
- a_trans->trans_Command=TKCMD_CLDATA;
- a_trans->trans_Timeout=10;
- DoTransaction(s_entity,t_entity,a_trans);
- }
- a_trans->trans_ReqDataActual=4;
- a_trans->trans_Command=TKCMD_CLEND;
- a_trans->trans_Timeout=10;
- DoTransaction(s_entity,t_entity,a_trans);
- LoseEntity(s_entity);
- } else
- {
- trans->trans_Error=999;
- ReplyTransaction(trans);
- }
- }
- else if(trans->trans_Command == TKCMD_MALIST)
- {
- /* Return a list of members in a conference */
-
- strcpy(con_name,(UBYTE *)trans->trans_RequestData+4);
- strcpy(hos_name,(UBYTE *)trans->trans_RequestData+36);
-
- s_entity = FindEntity(hos_name,"Conference_List",t_entity,NULL);
-
- if(s_entity)
- {
- trans->trans_Error=0;
- ReplyTransaction(trans);
-
- mem_p=4;
- if(c_node=(struct Con_Node *)CFindName(&conference_list,con_name))
- {
- for(m_node=(struct Machine_Node *)c_node->machine_list.lh_Head;m_node->mnode.ln_Succ;m_node=(struct Machine_Node *)m_node->mnode.ln_Succ)
- {
- strcpy(((UBYTE *)a_trans->trans_RequestData+mem_p),m_node->m_name);
- strcpy(((UBYTE *)a_trans->trans_RequestData+mem_p+32),m_node->alias);
-
- cycle_mode=0;
- for(mm_node=(struct Machine_Node *)c_node->machine_list.lh_Head;mm_node->mnode.ln_Succ;mm_node=(struct Machine_Node *)mm_node->mnode.ln_Succ)
- {
- if(!stricmp(mm_node->m_name,hos_name))
- {
- if(h_node=(struct Hide_Node *)CFindName(&mm_node->hide_list,m_node->m_name))
- {
- cycle_mode=h_node->mode;
- break;
- }
- }
- }
- *(ULONG *)((UBYTE *)a_trans->trans_RequestData+mem_p+64)=(ULONG)cycle_mode;
-
- mem_p+=68;
- if(mem_p == 480)
- {
- a_trans->trans_ReqDataActual=480;
- a_trans->trans_Command=TKCMD_CLDATA;
- a_trans->trans_Timeout=10;
- DoTransaction(s_entity,t_entity,a_trans);
- mem_p=4;
- }
- }
- if(mem_p != 4)
- {
- a_trans->trans_ReqDataActual=mem_p;
- a_trans->trans_Command=TKCMD_CLDATA;
- a_trans->trans_Timeout=10;
- DoTransaction(s_entity,t_entity,a_trans);
- }
- }
- a_trans->trans_ReqDataActual=4;
- a_trans->trans_Command=TKCMD_CLEND;
- a_trans->trans_Timeout=10;
- DoTransaction(s_entity,t_entity,a_trans);
- LoseEntity(s_entity);
- } else
- {
- trans->trans_Error=999;
- ReplyTransaction(trans);
- }
- }
- else if(trans->trans_Command == TKCMD_PRIVATE)
- {
- /* Transmit a private message to a member in x conference on y machine */
-
- strcpy(hos_name,(UBYTE *)trans->trans_RequestData+4);
- strcpy(con_name,(UBYTE *)trans->trans_RequestData+36);
- strcpy(pri_msg,(UBYTE *)trans->trans_RequestData+68);
-
- *(ULONG *)(a_trans->trans_RequestData)=*(ULONG *)(trans->trans_RequestData);
- strcpy(((UBYTE *)a_trans->trans_RequestData+4),((UBYTE *)trans->trans_RequestData+68));
- a_trans->trans_ReqDataActual=strlen(((UBYTE *)a_trans->trans_RequestData+4))+5;
- a_trans->trans_Command=TKCMD_CONDATA;
- ReplyTransaction(trans);
-
- if(c_node=(struct Con_Node *)CFindName(&conference_list,con_name))
- {
- for(m_node=(struct Machine_Node *)c_node->machine_list.lh_Head;m_node->mnode.ln_Succ;m_node=(struct Machine_Node *)m_node->mnode.ln_Succ)
- {
- if(!stricmp(m_node->m_name,hos_name))
- {
- a_trans->trans_Timeout=10;
- DoTransaction(m_node->s_entity,t_entity,a_trans);
- break;
- }
- }
- }
- }
- else if(trans->trans_Command == TKCMD_STATUS)
- {
- /* Change the status of a member in someone's list */
-
- strcpy(machine_name,(UBYTE *)trans->trans_RequestData+4);
- strcpy(con_name,(UBYTE *)trans->trans_RequestData+36);
- strcpy(hos_name,(UBYTE *)trans->trans_RequestData+68);
- cycle_mode=*(ULONG *)((UBYTE *)trans->trans_RequestData+100);
-
- error=1;
- if(c_node=(struct Con_Node *)CFindName(&conference_list,con_name))
- {
- for(m_node=(struct Machine_Node *)c_node->machine_list.lh_Head;m_node->mnode.ln_Succ;m_node=(struct Machine_Node *)m_node->mnode.ln_Succ)
- {
- if(!stricmp(m_node->m_name,hos_name))
- {
- error=0;
- if(h_node=(struct Hide_Node *)CFindName(&m_node->hide_list,machine_name))
- {
- h_node->mode=cycle_mode;
- }
- else if(h_node=(struct Hide_Node *)AllocMem(sizeof(struct Hide_Node),0))
- {
- h_node->hnode.ln_Name=h_node->h_name;
- strcpy(h_node->h_name,machine_name);
- h_node->mode=cycle_mode;
- AddTail(&m_node->hide_list,(struct Node *)h_node);
- }
- else
- {
- error=1;
- }
- }
- }
- }
- trans->trans_Error=error;
- ReplyTransaction(trans);
- }
- if(conference_list.lh_Head->ln_Succ == NULL)
- {
- done=1;
- }
- }
- }
- if(done)
- {
- break;
- }
- }
- while(trans = GetTransaction(entity))
- {
- trans->trans_Error=2;
- ReplyTransaction(trans);
- }
-
- TKSBase->TKS_Entity = NULL;
-
- a_trans->trans_ReqDataLength=516;
- FreeTransaction(a_trans);
- }
- DeleteEntity(t_entity);
- }
- DeleteEntity(entity);
- }
- if(StartupError)
- {
- TKSError = StartupError;
- Signal(TKSSMProc, TKSSignalMask);
- }
- Forbid();
- CloseLibrary(SvcBase);
- }
- }
-
-
-
-
- /*************************************************************************
- CFindName()
-
- Since FindName() is case sensitive, I can't use it...
-
- INPUTS: pointer to a list, pointer to a string to search for
- OUTPUT: NULL if not found, otherwise pointer to that node
- *************************************************************************/
- struct Node *CFindName(struct List *cc_list,UBYTE *string)
- {
- struct Node *r_value=NULL,*ln;
-
- for(ln=cc_list->lh_Head;ln->ln_Succ;ln=ln->ln_Succ)
- {
- if(!stricmp(ln->ln_Name,string))
- {
- r_value=ln;
- break;
- }
- }
- return(r_value);
- }
-